from rest_framework.views import APIView
from apps.coffee.models import fields
from utils.response import ApiResponse
from django.core.exceptions import ObjectDoesNotExist, ValidationError
import json

REQUIRED_FIELDS = ['name', 'field_type']  # 更换 type 为 field_type 避免关键字冲突
ALL_FIELDS = ['name', 'field_type', 'value', 'required', 'min', 'max','placeholder', 'show_count', 'status']
class FieldsView(APIView):
    """
    咖啡字段管理视图，处理字段的增删改查操作

    支持GET、POST、PUT、DELETE方法
    - GET: 获取所有字段信息
    - POST: 创建新字段
    - PUT: 更新指定ID的字段
    - DELETE: 删除指定ID的字段
    """
    def get(self, request):
        """
        获取所有字段信息

        参数:
            request (Request): DRF请求对象

        返回:
            ApiResponse: 包含所有字段数据的响应对象
        """
        data = list(fields.objects.all().values().order_by('-id'))
        for item in data:
            try:    
                item['value'] = json.loads(item['value'])
            except json.JSONDecodeError:
                pass
        return ApiResponse(data=list(data))
    
    # 获取允许使用的字段列表
    def get_fields_list(request):
        data = list(fields.objects.all().filter(status=1).values('id','name','field_type','status').order_by('-id'))
        return ApiResponse(data=data).render()
    
    def post(self, request):
        """
        创建新字段

        参数:
            request (Request): DRF请求对象，包含创建字段所需的数据

        返回:
            ApiResponse: 操作结果的响应

        异常:
            400: 缺少必要参数或验证失败
            500: 服务器内部错误
        """
        data = request.data
        if not all(data.get(field) for field in REQUIRED_FIELDS):
            return ApiResponse(code=400, message='缺少必要参数')

        try:
            #验证字段
            validated_data = self._validate_and_filter_fields(data)
            # 处理 value 字段 存储json格式
            if 'value' in data:
                validated_data['value'] = json.dumps(data['value'])
            #存储字段信息
            fields_obj = fields.objects.create(**validated_data)
            # 返回json格式数据
            return ApiResponse(message='创建成功', data={'id': fields_obj.id})
        except ValidationError as ve:
            return ApiResponse(code=400, message=str(ve))
        except Exception as e:
            return ApiResponse(code=500, message=str(e))
        

    def put(self, request, pk):
        """
        更新指定ID的字段

        参数:
            request (Request): DRF请求对象，包含更新数据
            pk (int): 要更新的字段主键ID

        返回:
            ApiResponse: 操作结果的响应

        异常:
            404: 指定ID的字段不存在
            400: 验证失败
            500: 服务器内部错误
        """
        try:
            fields_obj = fields.objects.get(pk=pk)
            validated_data = self._validate_and_filter_fields(request.data, is_update=True)
            if 'value' in validated_data:
                validated_data['value'] = json.dumps(validated_data['value'])
                
            for key, value in validated_data.items():
                setattr(fields_obj, key, value)
            fields_obj.save()
            return ApiResponse(message='更新成功')
        except ObjectDoesNotExist:
            return ApiResponse(code=404, message='字段不存在')
        except ValidationError as ve:
            return ApiResponse(code=400, message=str(ve))
        except Exception as e:
            return ApiResponse(code=500, message="服务器内部错误")
    
    def delete(self, request, pk):
        """
        删除指定ID的字段

        参数:
            request (Request): DRF请求对象
            pk (int): 要删除的字段主键ID

        返回:
            ApiResponse: 操作结果的响应

        异常:
            404: 指定ID的字段不存在
            500: 服务器内部错误
        """
        try:
            fields_obj = fields.objects.get(pk=pk)
            fields_obj.delete()
            return ApiResponse(message='删除成功')
        except ObjectDoesNotExist:
            return ApiResponse(code=404, message='字段不存在')
        except Exception as e:
            return ApiResponse(code=500, message="服务器内部错误")
        
    def _validate_and_filter_fields(self, data, is_update=False):
        """
        对字段数据进行验证和过滤，确保数据符合预期格式和约束条件
        
        该方法会遍历所有定义的字段，对每个字段进行类型检查和转换：
        - field_type 字段不能为空
        - required 和 showCount 字段必须是布尔值
        - min 和 max 字段必须是数字类型
        
        参数:
            data (dict): 包含待验证和过滤的字段数据字典
            is_update (bool): 指示当前操作是否为更新，默认为False
            
        返回:
            dict: 包含验证通过且适当转换后的字段字典
            
        异常:
            ValidationError: 当任何字段验证失败时抛出，包含具体错误信息
            
        特殊处理:
            - 对于更新操作(is_update=True)，仅处理存在于data中的字段
            - 对于布尔值字段，尝试将非布尔值转换为布尔值
            - 对于数值字段(min/max)，尝试将非数字值转换为浮点数
        """
        result = {}
        for field in ALL_FIELDS:
            value = data.get(field)
            if not is_update or (field in data):  # 更新时仅当字段存在才更新
                if field == 'field_type':
                    if not value:
                        raise ValidationError("字段类型不能为空")
                elif field in ['required', 'showCount']:
                    if not isinstance(value, bool):
                        try:
                            value = bool(value)
                        except ValueError:
                            raise ValidationError(f"{field} 必须为布尔值")
                elif field in ['min', 'max']:
                    if value is not None and not isinstance(value, (int, float)):
                        try:
                            value = float(value)
                        except ValueError:
                            raise ValidationError(f"{field} 必须为数字")
                result[field] = value
        return result